﻿// 29-191string容器基础.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;

int main()
{
    /*
    // 1）string()：创建一个长度为0的string对象（默认构造函数）。
    string s1;        // 创建一个长度为0的string对象
    cout << "s1=" << s1 << endl;       // 将输出s1=
    cout << "s1.capacity()=" << s1.capacity() << endl;    // 返回当前容量，可以存放字符的总数。
    cout << "s1.size()=" << s1.size() << endl;                   // 返回容器中数据的大小。
    cout << "容器动态数组的首地址=" << (void*)s1.c_str() << endl;
    s1 = "xxxxxxxxxxxxxxxxxxxx";
    cout << "s1.capacity()=" << s1.capacity() << endl;    // 返回当前容量，可以存放字符的总数。
    cout << "s1.size()=" << s1.size() << endl;                   // 返回容器中数据的大小。
    cout << "容器动态数组的首地址=" << (void*)s1.c_str() << endl;

    // 2）string(const char *s)：将string对象初始化为s指向的NBTS（转换函数）。
    string s2("hello world");
    cout << "s2=" << s2 << endl;       // 将输出s2=hello world
    string s3 = "hello world";
    cout << "s3=" << s3 << endl;       // 将输出s3=hello world

    // 3）string(const string & str)：将string对象初始化为str（拷贝构造函数）。
    string s4(s3);                                     // s3 = "hello world";
    cout << "s4=" << s4 << endl;       // 将输出s4=hello world
    string s5 = s3;
    cout << "s5=" << s5 << endl;       // 将输出s5=hello world

    // 4）string(const char* s, size_t n)：将string对象初始化为s指向的NBTS的前n个字符，即使超过了NBTS结尾。
    string s6("hello world", 5);
    cout << "s6=" << s6 << endl;       // 将输出s6=hello
    cout << "s6.capacity()=" << s6.capacity() << endl;    // 返回当前容量，可以存放字符的总数。
    cout << "s6.size()=" << s6.size() << endl;                   // 返回容器中数据的大小。
    string s7("hello world", 50);
    cout << "s7=" << s7 << endl;       // 将输出s7=hello未知内容
    cout << "s7.capacity()=" << s7.capacity() << endl;    // 返回当前容量，可以存放字符的总数。
    cout << "s7.size()=" << s7.size() << endl;                   // 返回容器中数据的大小。

    // 5）string(const string & str, size_t pos = 0, size_t n = npos)：
    // 将string对象初始化为str从位置pos开始到结尾的字符，或从位置pos开始的n个字符。
    string s8(s3, 3, 5);                               // s3 = "hello world";
    cout << "s8=" << s8 << endl;         // 将输出s8=lo wo
    string s9(s3, 3);
    cout << "s9=" << s9 << endl;         // 将输出s9=lo world
    cout << "s9.capacity()=" << s9.capacity() << endl;    // 返回当前容量，可以存放字符的总数。
    cout << "s9.size()=" << s9.size() << endl;                   // 返回容器中数据的大小。
    string s10("hello world", 3, 5);
    cout << "s10=" << s10 << endl;       // 将输出s10=lo wo
    string s11("hello world", 3);                // 注意：不会用构造函数5），而是用构造函数4）
    cout << "s11=" << s11 << endl;       // 将输出s11=hel

    // 6）template<class T> string(T begin, T end)：将string对象初始化为区间[begin, end]内的字符，
    //      其中begin和end的行为就像指针，用于指定位置，范围包括begin在内，但不包括end。

    // 7）string(size_t n, char c)：创建一个由n个字符c组成的string对象。
    string s12(8, 'x');
    cout << "s12=" << s12 << endl;       // 将输出s12=xxxxxxxx
    cout << "s12.capacity()=" << s12.capacity() << endl;    // s12.capacity()=15
    cout << "s12.size()=" << s12.size() << endl;                   // s12.size()=8
    string s13(30, 0);
    cout << "s13=" << s13 << endl;       // 将输出s13=
    cout << "s13.capacity()=" << s13.capacity() << endl;    // s13.capacity()=31
    cout << "s13.size()=" << s13.size() << endl;                   // s12.size()=30 
    */

    //1 创建一个string // 1）string()：创建一个长度为0的string对象（默认构造函数）。
    string s1;
    cout << "s1=" << s1 << endl; //输出s1=
    cout << "s1.capacity()=" << s1.capacity() << endl; //返回当前的容量 默认15
    cout << "s1.size()=" << s1.size() << endl;  //返回的是容器中数据的大小 0
    cout << "容器动态数组的首地址=" << (void*)s1.c_str() << endl;
    s1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    cout << "s1.capacity()=" << s1.capacity() << endl; //返回当前的容量 31
    cout << "s1.size()=" << s1.size() << endl;  //返回的是容器中数据的大小 28
    cout << "容器动态数组的首地址=" << (void*)s1.c_str() << endl;

    // 2）string(const char *s)：将string对象初始化为s指向的NBTS（转换函数）。
    string s2("hello world");
    cout << "s2=" << s2 << endl;
    string s3 = "hello world";
    cout << "s3=" << s3 << endl;

    // 3）string(const string & str)：将string对象初始化为str（拷贝构造函数）。
    string s4(s3);
    cout << "s4=" << s4 << endl;
    string s5 = s3;
    cout << "s5=" << s5 << endl;

    // 4）string(const char* s, size_t n)：将string对象初始化为s指向的NBTS的前n个字符，即使超过了NBTS结尾。
    string s6("hello world", 5);
    cout << "s6=" << s6 << endl;//hello
    cout << "s6.capacity()=" << s6.capacity() << endl; //返回当前的容量 15
    cout << "s6.size()=" << s6.size() << endl;  //返回的是容器中数据的大小 5
    string s7("hello world", 50);
    cout << "s7=" << s7 << endl;//worlds2=s3=s4=s5=s6=s6.capacit
    cout << "s7.capacity()=" << s7.capacity() << endl; //返回当前的容量  63
    cout << "s7.size()=" << s7.size() << endl;  //返回的是容器中数据的大小  50

    // 5）string(const string & str, size_t pos = 0, size_t n = npos)：
   // 将string对象初始化为str从位置pos开始到结尾的字符，或从位置pos开始的n个字符。
    string s8(s3, 3, 5); //s3= "hello world"
    cout << "s8=" << s8 << endl; //lo wo c 从索引是3获取长度是5
    string s9(s3, 3);
    cout << "s9=" << s9 << endl;  //lo world
    string s10("hello world", 3, 5);
    cout << "s10=" << s10 << endl; // lo wo
    string s11("hello world", 3);  //不会使用构造参数5 使用构造参数4
    cout << "s11=" << s11 << endl;//s11=hel
    
    // 6）template<class T> string(T begin, T end)：将string对象初始化为区间[begin, end]内的字符，
    //      其中begin和end的行为就像指针，用于指定位置，范围包括begin在内，但不包括end。


    // 7）string(size_t n, char c)：创建一个由n个字符c组成的string对象
    string s12(8, 'x');
    cout << "s12=" << s12 << endl;//s12=xxxxxxxx
    cout << "s12.capacity()=" << s12.capacity() << endl; //s12.capacity() = 15
    cout << "s12.size()=" << s12.size() << endl;//s12.size() = 8
    string s13(30, 0);
    cout << "s13=" << s13 << endl;
    cout << "s13.capacity()=" << s13.capacity() << endl; 
    cout << "s13.size()=" << s13.size() << endl;
    /*
        s13=
        s13.capacity()=31
        s13.size()=30
    */

    /*******************string的设计目标start**************************/

    /*
    char cc[8];   // 在栈上分配8字节的内存空间。

    // 把cc的内存空间用于字符串。
    strcpy(cc, "hello");
    cout << "cc=" << cc << endl << endl;

    // 把cc的内存空间用于int型整数。
    int* a, * b;
    a = (int *)cc;          // 前4个字节的空间用于整数a。
    b = (int *)cc + 4;   // 后4个字节的空间用于整数b。
    *a = 12345;
    *b = 54321;
    cout << "*a=" << *a << endl;
    cout << "*b=" << *b << endl << endl;

    // 把cc的内存空间用于double。
    double* d = (double*)cc;
    *d = 12345.7;
    cout << "*d=" << *d << endl << endl;

    // 把cc的内存空间用于结构体。
    struct stt
    {
        int a;
        char b[4];
    }*st;
    st = (struct stt*)cc;
    st->a = 38;
    strcpy(st->b, "abc");
    cout << "st->a=" << st->a << endl;
    cout << "st->b=" << st->b << endl << endl;

    // void* malloc(size_t size);
    //char* cc1 = (char*)malloc(8);
    //int* cc1 = (int*)malloc(8);

    */
    char cc[8]; //从栈上分配8个字节的内存空间
    //把cc的内存空间用于字符串
    strcpy_s(cc, "helllo");
    cout << "cc=" << cc << endl << endl;
    int* a, * b;
    a = (int*)cc; //前四个字节的空间用于整数a
    b = (int*)cc + 4; //前四个字节的空间用于整数b
    *a = 12345;
    *b = 54321;
    cout << "*a=" << *a << endl;
    cout << "*b=" << *b << endl;


    double* d = (double*)cc;
    *d = 12345.7;
    cout << "*d=" << *d << endl;

    struct stt {
        int a;
        char b[4];
    }*st;
    st = (struct stt*)cc;
    st->a = 38;
    strcpy_s(st->b, "abc");
    /*
    st->a=38
    st->b=abc
    */
    cout << "st->a=" << st->a << endl;
    cout << "st->b=" << st->b << endl;


    /*******************string的设计目标end**************************/

    /******************************其他操作*********************************/
    /*struct st_girl {   // 超女结构体。
        int    bh;
        char name[30];
        bool yz;
        double weight;
        string memo;
    } girl;

    cout << "超女结构体的大小：" << sizeof(struct st_girl) << endl;

    string buffer;  // 创建一个空的string容器buffer。

    // 生成10名超女的信息，存入buffer中。
    for (int ii = 1; ii <= 10; ii++)
    {
        // 对超女结构体成员赋值。    
        memset(&girl, 0, sizeof(struct st_girl));
        girl.bh = ii;
        sprintf(girl.name, "西施%02d", ii);
        girl.yz = true;
        girl.weight = 48.5 + ii;
        girl.memo = "中国历史第一美女。";

        // 把超女结构追加到buffer中。
        buffer.append((char*)&girl, sizeof(struct st_girl));
    }

    cout << "buffer.capacity()=" << buffer.capacity() << endl;  // 显示容量。
    cout << "buffer.size()=" << buffer.size() << endl;  // 显示实际大小。

    // 用一个循环，把buffer容器中全部的数据取出来。
    for (int ii = 0; ii < buffer.size() / sizeof(struct st_girl); ii++)
    {
        memset(&girl, 0, sizeof(struct st_girl));  // 初始化超女结构体。

        // 把容器中的数据复制到超女结构体。
        memcpy(&girl, buffer.data() + ii * sizeof(struct st_girl), sizeof(struct st_girl));
        // buffer.copy((char*)&girl, sizeof(struct st_girl), ii * sizeof(struct st_girl));

        // 显示超女结构体成员的值。
        cout << "bh=" << girl.bh << ",name=" << girl.name << ",yz=" << girl.yz << ",weight="
            << girl.weight << ",memo=" << girl.memo << endl;
    }
    */


    //extern void *memset(void *buffer, int ch, int count)
    /*
        buffer：为指向一片内存空间的指针（任意类型）；
        ch: 要被设置的值。该值以 int 形式传递；
        count：被设置为该值的字节数。
    */
    struct st_girl {
        int bh;
        char name[30];
        bool yz;
        double weight;
        string momo;
    }girl;
    cout << "超女结构体的大小:" << sizeof(struct st_girl) << endl;
    string buffer;// 创建一个空的string容器的buffer

    for (int ii = 0; ii < 10; ii++)
    {
        //对超女的结构体的成员赋值
        memset(&girl, 0, sizeof(struct st_girl));
        girl.bh = ii;
        sprintf_s(girl.name, "西施%02d", ii);
        girl.yz = true;
        girl.weight = 48.5 + ii;
        girl.momo = "施";

        //把超女的结构体追加到buffer中
        buffer.append((char*)&girl, sizeof(struct st_girl));
    }

    for (int j = 0; j < 10; j++)
    {
        memset(&girl, 0, sizeof(struct st_girl));
        //把容器中的数据复制到超女结构体
        memcpy(&girl, buffer.data() + j * sizeof(struct st_girl), sizeof(struct st_girl));

        //显示超女结构体的之
        cout << "bh=" << girl.bh << ",name=" << girl.name << ",yz" << girl.yz << ",weight="
            << girl.weight << ",memo=" << girl.momo << endl;
    }
   


    /******************************其他操作*********************************/


    /*********5连接操作start********/
    string _2str1 = "hello";
    string _2str2 = "hello";
    _2str1.append(8, 'x');
    _2str2.append("xxx");

    /*********5连接操作end********/

    /*********6交换操作start********/
    /*
    _6s1的内容:1111111111
    _6s2的内容:2222222222
    _6s1的地址是:000000DE907AF4A0
    _6s2的地址是:000000DE907AF4E0
    _6s1的内容:2222222222
    _6s2的内容:1111111111
    _6s1的地址是:000000DE907AF4A0
    _6s2的地址是:000000DE907AF4E0
    */
    string _6s1 = "1111111111";
    string _6s2 = "2222222222";
    cout << "_6s1的内容:" << _6s1 << endl;
    cout << "_6s2的内容:" << _6s2 << endl;
    cout << "_6s1的地址是:" << (void*)_6s1.data() << endl;
    cout << "_6s2的地址是:" << (void*)_6s2.data() << endl;
    _6s1.swap(_6s2);
    cout << "_6s1的内容:" << _6s1 << endl;
    cout << "_6s2的内容:" << _6s2 << endl;
    cout << "_6s1的地址是:" << (void*)_6s1.data() << endl;
    cout << "_6s2的地址是:" << (void*)_6s2.data() << endl;
    //交换了内容 但是地址没有被交换
    /*********6交换操作start********/


    /*字符串的分割操作start*/
    //todo
    /*字符串的分割操作end*/
}
